package com.jet.multichat.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 
 * ����� �������
 * 1) � ������ execute 
 * 1.1) ������ ������ ��� ������ ���������, ��������� � ������� ������� - ��� ��������� ������
 * 1.2) ������ �����, ������� ������� ����� ���������������� ����������
 *
 */
public class ChatServer {
	private int port; 
	private int id = 0;

	//[DF] XXX: public?! �� ���� ������ ������ ������ � ����� �������� ������, ����� ���� �������� �������������.
	//[DF] ������ ��� ��� ��������, � ��� ������, ��� � �������...
	//[ek] XXX why List? why not Set or Map ?
	//private ArrayList<ChatThread> clientThreadsList = new ArrayList<ChatThread>();
	private static Map<String, ChatThread> chatThreads = new HashMap <String, ChatThread>();

	//[ek] TODO remove dead code
	//alive by refactor
	public ChatServer(int port) {
		this.port = port;
	}
	
	public int getId() {
		return id;
	}

    public synchronized Map<String, ChatThread> getChatThreads() {
    	return chatThreads;
    }

	public synchronized void addChatThread(ChatThread chatThread) {
		chatThreads.put(chatThread.getLogin(), chatThread);
	}

	public synchronized void removeChatThread(ChatThread chatThread) {
		chatThreads.remove(chatThread.getLogin());
	}

    public int getPort() {
        return port;
    }
    
    public synchronized void increaseId() {
		this.id = this.id + 1;
	}

	private void execute() {
		//[ek] XXX overkill?
		//ExecutorService executorService = Executors.newCachedThreadPool(); //for remind comment reason
		//changed to new Thread(Runnable).start();

		ServerSocket serverSocket = null;
		try {
			new Thread(new ChatServerConsoleReaderThread(this, new BufferedReader(new InputStreamReader(System.in)))).start();

			serverSocket = new ServerSocket(getPort());
			consoleMessage("Server started", new Date());

			while(true) {
				Socket socket = serverSocket.accept();
				new Thread(new ChatThread (this, socket, getId())).start();
				//consoleMessage(socket.getInetAddress().getHostAddress(), new Date());
				consoleMessage(socket.getLocalAddress().getHostAddress(), new Date());
				increaseId();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (serverSocket != null) {
				try {
					serverSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void consoleMessage(String string, Date date) {
		System.out.println(date.toString() + ": " + string);
	}

	public void consoleMessage(String string) {
		System.out.println(string);
	}

	public static void main(String[] arg) {
		ChatServer chatServer = new ChatServer(30030);
		chatServer.execute();
	}

}
